home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d11
/
graph11.arc
/
GRAPHER.BAK
< prev
next >
Wrap
Text File
|
1991-08-21
|
15KB
|
596 lines
(*$N+*)
program BGIGrapher;
uses
Crt, Dos, Graph;
Const
MaxData = 600;
Type
Data = array [1..MaxData] of Extended;
GraphContents = Record
X,Y:Data;
XMin,XMax,YMin,YMax:Extended;
AbsXMax,AbsYMax:Extended;
end;
var
FileName,Labels: string;
Graphs:GraphContents; (* Some important info. on data *)
NoOfData,i,Starting,Ending:integer;
GraphDriver : integer; (* The Graphics device driver *)
GraphMode : integer; (* The Graphics mode value *)
MaxX, MaxY : word; (* The maximum resolution of the screen *)
ErrorCode : integer; (* Reports any graphics errors *)
MaxColor : word; (* The maximum color value available *)
OldExitProc : Pointer; (* Saves exit procedure address *)
(* Display help screen *)
procedure HelpScreen;
begin
Writeln ('FreeWare Experimental Grapher ');
Writeln ('(C)opyright TakaPuna 1991 Version 1.1');
Writeln ('Portions of the codes are (C)opyrighted by Borland International ');
Writeln;
Writeln ('Command Line Options:');
Writeln (' FileName [All Labels] [Starting Ending Labels] ');
Writeln;
Writeln (' FileName : Data file from a text file ');
Writeln (' Starting : Starting index to view (integer) ');
Writeln (' Ending : Ending index to view (integer) ');
Writeln (' Labels : Axis labels ');
Writeln;
Writeln ('Example:');
Writeln ('- To display all points and label the axis as');
Writeln (' "X vs Y" >: Grapher FileName All X vs Y ');
Writeln ('- To display points #10 to #20 and label the axis as');
Writeln (' "X vs Y" >: Grapher FileName 10 20 X vs Y ');
Writeln ('- All parameter must appear in order !!!!');
Halt (1);
end;
(*$F+*)
(* Trap run time errors *)
procedure UserExitProc;
begin
ExitProc := OldExitProc; (* Restore exit procedure address *)
CloseGraph;
end; (* UserExitProc *)
(*$F-*)
procedure Initialize;
(* Initialize graphics and report any errors that may occur *)
var
InGraphicsMode : boolean; (* Flags initialization of graphics mode *)
PathToDriver : string; (* Stores the DOS path to *.BGI & *.CHR *)
begin
(* when using Crt and graphics, turn off Crt's memory-mapped writes *)
DirectVideo := False;
OldExitProc := ExitProc; (* save previous exit proc *)
ExitProc := @UserExitProc; (* insert our exit proc in chain *)
PathToDriver := '';
repeat
(*$IFDEF Use8514*) (* check for Use8514 $DEFINE *)
GraphDriver := IBM8514;
GraphMode := IBM8514Hi;
(*$ELSE*)
GraphDriver := Detect; (* use autodetection *)
(*$ENDIF*)
InitGraph(GraphDriver, GraphMode, PathToDriver);
ErrorCode := GraphResult; (* preserve error return *)
if ErrorCode <> grOK then (* error? *)
begin
Writeln('Graphics error: ', GraphErrorMsg(ErrorCode));
if ErrorCode = grFileNotFound then (* Can't find driver file *)
begin
Writeln('Enter full path to BGI driver or type <Ctrl-Break> to quit:');
Readln(PathToDriver);
end
else
Halt(1); (* Some other error: terminate *)
end;
until ErrorCode = grOK;
MaxColor := GetMaxColor; (* Get the maximum allowable drawing color *)
MaxX := GetMaxX; (* Get screen resolution values *)
MaxY := GetMaxY;
end; (* Initialize *)
(* Returns true if file exists *)
function FileExist (FileName:string):boolean;
Var
F:Text;
begin
(*$I-*)
Assign (F,FileName);
Reset (F);
FileExist:= IOResult = 0;
(*$I+*)
end;
function Int2Str(L : LongInt) : string;
(* Converts integer to string *)
var
S : string;
begin
Str(L, S);
Int2Str := S;
end; (* Int2Str *)
function Str2Int(S:string):integer;
(* Converts string to integer *)
var
L,Code:integer;
begin
Val(S,L,Code);
if Code <> 0 then
begin
Writeln ('Integer values expected as parameters.');
Halt(1);
end
else
Str2Int:=L;
end;
function Real2Str(L : Extended) : string;
(* Converts Extended numbers to string *)
var
S : string;
begin
Str(L:0, S);
Real2Str := S;
end; (* Real2Str *)
(* Check if the Parameter is equal to the Switch *)
function IsEqual(Parameter,Switch:String):boolean;
var
Quit:boolean;
begin
Quit:=false;
i:=0;
While not Quit do
begin
Inc(i);
Quit:=(Upcase(Switch[i])<>Upcase(Parameter[i])) or (i=Length(Switch));
end;
if i=Length(Switch) then
IsEqual:=true
else
IsEqual:=false;
end;
procedure DefaultColors;
(* Select the maximum color in the Palette for the drawing color *)
begin
SetColor(MaxColor);
end; (* DefaultColors *)
procedure FullPort;
(* Set the view port to the entire screen *)
begin
SetViewPort(0, 0, MaxX, MaxY, ClipOff);
end; (* FullPort *)
procedure MainWindow(Header : string);
(* Make a default window and view port for demos *)
begin
DefaultColors; (* Reset the colors *)
SetTextStyle(SmallFont, HorizDir, 5);
SetTextJustify(CenterText, TopText); (* Left justify text *)
FullPort; (* Full screen view port *)
OutTextXY(MaxX div 2,0, Header); (* Draw the header *)
(* Draw main window *)
SetViewPort (Round(0.2*MaxX),Round(0.1*MaxY),Round(0.9*MaxX),Round(0.7*MaxY),
ClipOff);
end; (* MainWindow *)
procedure WaitToGo;
(* Wait for the user to abort the program or continue *)
const
Esc = #27;
var
Ch : char;
begin
repeat until KeyPressed;
Ch := ReadKey;
if ch = #0 then ch := readkey; (* trap function keys *)
if Ch = Esc then
Halt(0) (* terminate program *)
else
ClearDevice; (* clear screen *)
end; (* WaitToGo *)
(* Initialize the Graph Record *)
procedure InitGlobal (UserGivenFile:string);
var
FileName:text;
j:integer;
a,b:Extended;
TXmax,TXmin,TYmax,TYmin:Extended;
Quit:boolean;
begin
NoOfData:=0;
j:=1;
i:=1;
ClrScr;
Quit:=false;
Assign (FileName,UserGivenFile);
Reset (FileName);
While not Quit do
begin
(*$I-*)
Readln (FileName,a,b);
(*$I+*)
if IOResult = 0 then
begin
if ParamCount > 2 then
begin
if (j>=Starting) and (j<=Ending) then
begin
Graphs.X[i]:=a;
Graphs.Y[i]:=b;
Inc (NoOfData);
Inc (i);
end;
end
else
begin
Graphs.X[i]:=a;
Graphs.Y[i]:=b;
Inc (NoOfData);
Inc(i);
end;
Inc(j);
end
else
Writeln ('Some Invalid entries skipped ');
Quit:=(NoOfData = MaxData) or EOF(FileName);
end; (* While not Quit *)
Close (FileName);
if (NoOfData = MaxData) then
begin
Writeln ('Too many data .....Aborting program. Maximum data = ',MaxData);
Halt(1);
end
else
begin
TXmax:=Graphs.X[1]; (* find the maximum and the minimum of data *)
TXMin:=Graphs.X[1];
TYMax:=Graphs.Y[1];
TYMin:=Graphs.Y[1];
for i:=1 to NoOfData do
begin
if Graphs.X[i] > TXMax then
TXMax:=Graphs.X[i];
if Graphs.X[i] < TXMin then
TXMin:=Graphs.X[i];
if Graphs.Y[i] > TYMax then
TYMax:=Graphs.Y[i];
if Graphs.Y[i] < TYMin then
TYMin:=Graphs.Y[i];
end;
Graphs.XMax:=TXMax;
Graphs.XMin:=TXMin;
Graphs.YMax:=TYMax;
Graphs.YMin:=TYMin;
if (Abs(TXmin) > Abs(TXMax)) then
Graphs.AbsXMax:=Abs(TXMin)
else
Graphs.AbsXMax:=Abs(TXMax);
if (Abs(TYmin) > Abs(TYMax)) then
Graphs.AbsYMax:=Abs(TYMin)
else
Graphs.AbsYMax:=Abs(TYMax);
end;
end; (* InitGlobal *)
procedure Status(Msg : string);
(* report the status of graph *)
begin
FullPort;
DefaultColors;
SetTextJustify(CenterText, TopText);
SetLineStyle(SolidLn, 0, NormWidth);
SetFillStyle(EmptyFill, 0);
OutTextXY(MaxX div 2,MaxY-(TextHeight('M')+20),Msg);
(* Draw main window back again *)
SetViewPort (Round(0.2*MaxX),Round(0.1*MaxY),Round(0.9*MaxX),Round(0.7*MaxY),
ClipOff);
end; (* Status *)
procedure DrawBorder;
(* Draw a border around the current view port
and labels the axis *)
var
ViewPort : ViewPortType;
IncX,IncY,Start:Extended;
Mult:Extended;
begin
if (Graphs.XMax > 0) and (Graphs.XMin >= 0) then
IncX:=(Graphs.XMax-Graphs.XMin)/4;
if (Graphs.XMax < 0) and (Graphs.XMin < 0) then
IncX:=(-Abs(Graphs.XMax)+Abs(Graphs.XMin))/4;
if (Graphs.XMax >= 0) and (Graphs.XMin < 0) then
IncX:=(Abs(Graphs.XMax)+Abs(Graphs.XMin))/4;
if (Graphs.YMax=Graphs.YMin) then
IncY:=Abs(Graphs.YMax/4)
else
begin
If (Graphs.YMax > 0) and (Graphs.YMin >= 0) then
IncY:=(Graphs.YMax-Graphs.YMin)/4;
If (Graphs.YMax < 0) and (Graphs.YMin < 0) then
IncY:=(-Abs(Graphs.YMax)+Abs(Graphs.YMin))/4;
if (Graphs.YMax >= 0) and (Graphs.YMin < 0) then
IncY:=(Abs(Graphs.YMax)+Abs(Graphs.YMin))/4;
end;
Status ('Step size X = '+Real2Str(IncX)+
' Step size Y ='+Real2Str(IncY));
DefaultColors;
SetLineStyle(SolidLn,0, ThickWidth);
GetViewSettings(ViewPort);
SetTextStyle(SmallFont, HorizDir, 5);
with ViewPort do
begin
Rectangle(0, 0, x2-x1, y2-y1);
(* Rectangle edges *)
Line (X2-X1+4,0,X2-X1-1,0);
Line (0,-4,0,1);
Line (0,Y2-Y1+4,0,Y2-Y1-1);
Line (-4,0,1,0);
(* Draw ticks on Y axis *)
Mult:=0.25;
for i:=1 to 4 do
begin
Line (X2-X1+4,Round(Mult*(Y2-Y1)),X2-X1-1,Round(Mult*(Y2-Y1)));
Line (-4,Round(Mult*(Y2-Y1)),1,Round(Mult*(Y2-Y1)));
Mult:=Mult+0.25;
end;
(* Label the Y Axis *)
if (Graphs.YMax=Graphs.YMin) then
Start:=Graphs.YMax-(2*IncY)
else
Start:=Graphs.YMin;
Mult:=1;
for i:=1 to 5 do
begin
OutTextXY (-4-TextWidth(Real2Str(Start)),Round(Mult*(Y2-Y1))-TextHeight(Real2Str(Start)),
Real2Str(Start));
Mult:=Mult-0.25;
Start:=Start+IncY;
end;
(* Draw ticks on X axis *)
Mult:=0.25;
for i:=1 to 4 do
begin
Line (Round(Mult*(X2-X1)),-4,Round(Mult*(X2-X1)),1);
Line (Round(Mult*(X2-X1)),Y2-Y1+4,Round(Mult*(X2-X1)),Y2-Y1-1);
Mult:=Mult+0.25;
end;
(* Label the X axis *)
Mult:=0;
Start:=Graphs.Xmin;
for i:=1 to 5 do
begin
OutTextXY (Round(Mult*(X2-X1))-TextWidth(Real2Str(Start)) div 4,Y2-Y1+TextHeight(Real2Str(Start)),
Real2Str(Start));
Mult:=Mult+0.25;
Start:=Start+IncX;
end;
end; (* with ViewPort *)
end; (* DrawBorder *)
procedure ScaleData;
(* Scale the data such that it will fall inside the viewport *)
var
ShiftX,ShiftY:integer;
Xscale,YScale:Extended;
ViewPort:ViewPortType;
begin
GetViewSettings(ViewPort);
With ViewPort do
begin
(* Put some conditions on X *)
if (Graphs.XMax=Graphs.XMin) then
begin
Writeln ('Data does not make sense ');
Halt(1);
end;
if (Graphs.XMax > 0 ) and (Graphs.XMin > 0) then (* XMax > 0 *)
begin (* XMin > 0 *)
XScale:=(X2-X1)/(Graphs.XMax-Graphs.XMin);
ShiftX:=-Round(Graphs.XMax*XScale-X2+X1);
end
else
begin
if Graphs.XMax > 0 then (* absolutely no zero *)
begin
ShiftX:=Round((1-(Graphs.XMax/(Graphs.XMax + Abs(Graphs.Xmin))))*(X2-X1));
XScale:=(X2-(ShiftX+X1))/(Graphs.XMax);
if XScale = 0 then
XScale:=(X2-X1)/(Graphs.AbsXMax)
end
else
begin
XScale:=(X2-X1)/(Graphs.XMax-Graphs.XMin);
ShiftX:=-Round(Graphs.XMax*XScale-X2+X1);
end;
end;
(* Put Some condition on Y *)
if (Graphs.YMax=Graphs.YMin) then
begin
for i:=1 to NoOfData do
begin
Graphs.X[i]:=Graphs.X[i]*XScale+ShiftX;
Graphs.Y[i]:=0.5*(Y2-Y1);
end;
end
else
begin
if (Graphs.YMax > 0 ) and (Graphs.YMin > 0) then (* YMax > 0 *)
begin (* YMin > 0 *)
YScale:=(Y2-Y1)/(Graphs.YMax-Graphs.YMin);
ShiftY:=-Round(Graphs.YMax*YScale-y2+y1);
end
else
begin
if (Graphs.YMax > 0) then
begin
ShiftY:=Round((1-(Graphs.YMax/(Graphs.YMax + Abs(Graphs.Ymin))))*(Y2-Y1));
YScale:=(Y2-(ShiftY+Y1))/Graphs.YMax;
if YScale= 0 then
YScale:=(Y2-Y1)/(Graphs.AbsYMax);
end
else
begin
YScale:=(Y2-Y1)/(Graphs.YMax-Graphs.YMin);
ShiftY:=-Round(Graphs.YMax*YScale-y2+y1);
end;
end;
for i:=1 to NoOfData do
begin
Graphs.X[i]:=Graphs.X[i]*XScale+ShiftX;
Graphs.Y[i]:=Graphs.Y[i]*YScale+ShiftY;
end;
end;
end;
end; (* Scale Data *)
procedure Plot;
(* plot the given data in the array *)
var
ViewPort:ViewPortType;
begin
SetLineStyle(SolidLn, 0, NormWidth);
GetViewSettings(ViewPort);
With ViewPort do
begin
MoveTo (Round(Graphs.X[1]),
(Y2-Y1)-Round(Graphs.Y[1]));
for i:=2 to NoOfData do
LineTo (Round(Graphs.X[i]),
(Y2-Y1)-Round(Graphs.Y[i]));
end;
end; (* Plot *)
(* Handles command line input *)
procedure CommandLine;
begin
if ParamCount = 0 then
HelpScreen
else
begin
Labels:='';
FileName:=ParamStr(1);
if NOT FileExist(FileName) then
begin
Writeln ('File ',FileName,' does not exist.');
Halt(1);
end;
if ParamCount > 2 then
begin
if Not (IsEqual(ParamStr(2),'All')) then
begin
Starting:=Str2Int(ParamStr(2));
Ending:=Str2Int(ParamStr(3));
if (Starting > Ending) then
begin
Writeln ('Starting index must be less than ending index. ');
Halt(1);
end;
for i:=4 to ParamCount do
Labels:=Labels +' '+ ParamStr(i);
end
else
begin
Starting:=1;
Ending:=MaxData;
for i:=3 to ParamCount do
Labels:=Labels +' '+ ParamStr(i);
end;
end;
end;
end;
begin (* program body *)
ClrScr;
CommandLine;
InitGlobal (FileName);
Initialize;
MainWindow (Labels);
ScaleData;
DrawBorder;
Plot;
WaitToGo;
end.